
; B5LO-1.INS - BYE5 insert for Lobo MAX-80 with CP/M+ - 08/17/85
;
;		Z80 SIO and 8116 baudrate generator
;
;
;	      NOTE: This is an insert, not an overlay
;
;=   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;
; 08/17/85  Updated B+LO-1.INS for BYE5 	- James Dunn
;
;=   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
;
;
;The following define the address to use.
;
SIODA	EQU	0F7E4H		; Modem data window
SIOCA	EQU	0F7E5H		; Modem control window
BAUDA	EQU	0F7D0H		; Baud rate window
;
;
; The following are baud rates for BAUDA
;
B300	EQU	05H		; 300 bps
B1200	EQU	07H		; 1200 bps
B2400	EQU	0AH		; 2400 bps
;
;
;-----------------------------------------------------------------------
;
; See if there is a carrier.  If not, return with the zero flag set.
;
MDCARCK:MVI	A,10H		; Reset status
	STA	SIOCA
	LDA	SIOCA		; Get status
	ANI	8		; Check for data carrier
	RET			; Return
;.....
;
;
; This routine will turn off the serial card and hang up the phone.
;
MDINIT:	MVI	A,18H		; Reset channel
	STA	SIOCA
	MVI	A,4		; Setup to write register 4
	STA	SIOCA
	MVI	A,44H		; 16x, 1 stop bit, no parity
	STA	SIOCA
	MVI	A,1		; Setup to write register 1
	STA	SIOCA
	MVI	A,0		; Value to write to register 1
	STA	SIOCA
	MVI	A,5		; Setup to write register 5
	STA	SIOCA
	MVI	A,0		; DTR off, RTS off
	STA	SIOCA
	PUSH	B		; Save in case it's being used elsewhere
	MVI	B,20		; 2 second delay
;
OFFTI:	CALL	DELAY		; 0.1 second delay
	DCR	B
	JNZ	OFFTI		; Keep looping until finished
	POP	B		; Restore bc
	MVI	A,3		; Setup to write register 3
	STA	SIOCA
	MVI	A,0C1H		; 8 bits/char, RX enable
	STA	SIOCA
	MVI	A,5		; Setup to write register 5
	STA	SIOCA
	MVI	A,0EAH		; DTR on, 8 bits/char, TX enable, RTS on
	STA	SIOCA
;
	 IF	IMODEM		; If using a smartmodem
	CALL	IMINIT		; Go initialize smartmodem now
	 ENDIF			; Imodem
;
	RET			; Return
;.....
;
;
; Input a character
;
MDINP:	LDA	SIODA		; Get character
	RET			; Return
;.....
;
;
; Check the status to see if a character is available.  Return with zero
; flag set if not.  If yes, use 0FFH to clear the flag.
;
MDINST:	LDA	SIOCA		; Get status
	ANI	1		; Got a character?
	RZ			; Return if none
	ORI	0FFH		; Otherwise, set the proper flag
	RET			; And return
;.....
;
;
; Send a character to the modem.
;
MDOUTP:	STA	SIODA		; Send it
	RET			; Return
;.....
;
;
; See if the outputa is ready for another character.
;
MDOUTST:LDA	SIOCA
	ANI	4		; Mask it
	RET			; Return
;.....
;
;
; Reintialize the modem and hang up the phone by dropping DTR and
; leaving it inactive.
;
MDQUIT:	 IF	IMODEM		; If using a smartmodem
	CALL	IMQUIT		; Tell it to shut down
	 ENDIF			; Imodem
;
;
; Called by the main program after the caller types BYE
;
MDSTOP:	MVI	A,5		; Setup to write register 5
	STA	SIOCA
	MVI	A,0		; DTR off, RTS off
	STA	SIOCA
	RET
;.....
;
;
; If you do not support a particular baud rate, put it here before
; SETINV:
;
SETINV:	ORI	0FFH		; Make sure zero flag is not set
	RET			; Return
;.....
;
;
SET300:	MVI	A,B300		; Load rate
	JMP	SETBAUD
;
SET1200:MVI	A,B1200		; Load rate
	JMP	SETBAUD
;
SET2400:MVI	A,B2400		; Load rate
	JMP	SETBAUD
;
SETBAUD:STA	BAUDA		; Send first byte of command
	MVI	A,10H		; Reset ext/status interrupts
	STA	SIOCA
	XRA	A		; Say rate is ok
	RET			; Return
;.....
;
;
;=======================================================================
;		Lobo MAX-80 CP/M Plus bank control area
;=======================================================================
;
;						jjd - 14 Jul 85
; Ok, this is my current understanding of how and why BYE5 needs
; control over bank switching.	Character I/O goes through the
; BDOS and through the BIOS to the actual, machine dependent,
; character I/O routines.  The physical character I/O routines
; under Plus on the MAX-80 are in common, non-banked memory, around
; the F2xxH area.  Now, normally, character I/O goes from the
; user application program (like an RBBS or whatever) running in
; the TPA in bank 1, to the part of the BDOS in common memory, to
; the part of the BIOS in common memory.  When BYE is in control,
; the character I/O is captured as it is sent to the BIOS routines,
; and sent through the famous local/remote virtual "Y" connector.
; The BYE "Y" connector sits in the RSX.  This RSX is not used the
; way DRI intended, where it would filter BDOS calls, but rather, it
; is used to grab and save some memory for its console trapping code.
; Now comes the good news for we MAX-80 people.  Lobo decided to
; give us 32k of common memory.  I'm not sure if that really produces
; an efficient CP/M Plus machine, but it sure makes RSXing easy as
; compared to the Osborne Exec or the Morrow machine.  We can leave
; our BYE "Y" code right in the RSX.  George and Paul had to move
; their code onto a "safe" area in the common BDOS.
;
; So, by now you should be wondering why we MAXers should have to worry
; about bank switching at all.  Well, here's why.  Way back I said
; normally I/O from appl prgm via BDOS via BIOS, right, well, some I/O,
; like CP/M error messages, comes from bank 0, the banked portions of
; the BDOS and BIOS.  But, that's not the problem, directly.  These I/O
; calls go through the BIOS jump table at F200 and display ok.
; The problem is that when I/O originates from bank 0, and BYE
; gets control at each CONOUT call, it does its normal job of checking
; the current user/drive values at 00004H and comparing them with
; the values plugged in at 003DH and 003FH.  Right, you got it, these
; values are, of course, over in bank 1, not in bank 0.  Then to
; put the icing on the cake, when a drive or user check fails,
; BYE sets up to A0: does a JP 0000H to get a warm boot .....
; and we just went south on that one.
;
; So, we realize that even when we do character I/O from any bank, we
; need bank 1 current to check those magic values in the low page of
; bank 1, and to allow a warm boot via JP 0000H.  The code runs ok
; in the common memory, and the stack space is not lost.
; This is why I didn't bother with adjusting any stack pointers.
; Another solution which I think should work, would be to grab these
; magic values in the low page of bank 1, MAXUSER, WHEEL and MAXDRIV,
; and put them right into the RSX.
; This would also need the read/write at 0004H to be cancelled, and
; use only the SCB values.  I think this approach would work on the
; MAX, and might even work on other machines, if they have enough
; extra room?, not sure.
;
; Possible GOTCHAs ::  Ok, when bank switching, we have to switch
; back to the bank from hence we came.	When using the bios as
; supplied from Lobo, this value, named CBNK in the Lobo Source,
; and in the DRI CP/M 3 System Guide, is at address 0F2A5H.  See
; it at the end of the file XROOT.MAC as supplied from Lobo.
; Also, I call BNKSEL directly at F29FH.  Now these will work fine
; unless you modify any of the BIOS source by adding or removing
; bunches of code.  These values will change, and you will have to
; snoop around and find the new values.  If you can handle BIOS
; modification, you can handle this change.
;
; Also, during testing, I got strange results when I turned on the
; RSPEED equate.  I'm not sure why, so I am leaving it off...
; I probably wouldn't use it anyway.
;
;-----------------------------------------------------------------------
;
; Perform system or hardware dependent PRE-processing.
; The following code will be executed by the PATCH subroutine before the
; BIOS jump table is overwritten.  This will allow the BIOS intercept
; routines to operate as early as the initial signon message display.
;
;
; Replace the NEWJTBL BIOS routing table with our own
;
MDPREP:	LXI	H,JTBLNEW	; Get replacement table address
	LXI	D,NEWJTBL	; Get address to overwrite
	LXI	B,JTBLEN	; Get number of bytes to overwrite
	DB	0EDH,0B0H	; Z80 ldir instruction
	RET
;.....
;
;
; Perform system or hardware dependent POST-processing.
; The following code will be executed by the EXCPM routine before re-
; turning control to CP/M Plus when the BYE5 program is terminated.
;
MDPOSP:	RET
;.....
;
;
WBCOMN:	CALL	SWIN		; Warm boot
	JMP	MBOOT
;.....
;
;
CSCOMN:	CALL	SWIN		; Console status
	CALL	MSTAT
	JMP	SWOUT
;.....
;
;
CICOMN:	CALL	SWIN		; Console input
	CALL	MINPUT
	JMP	SWOUT
;.....
;
;
COCOMN:	CALL	SWIN		; Console output
	CALL	MOUTPUT
	JMP	SWOUT
;.....
;
;
CBNK	EQU	0F2A5H		; Address of the current bank byte
BNKSEL	EQU	0F29FH		; Entry point of BIOS bank select
RTBNK	DS	1		; Place to store bank to return to
;
SWIN:	PUSH	A		; Bank switch in routine
	LDA	CBNK		; Get the bank we are switching from
	STA	RTBNK		; Store so we know where to switch back
	MVI	A,1		; We are going to switch to bank 1
	CALL	BNKSEL		; Switch to bank 1
	POP	A		; Restore 'A' and flags
	RET
;.....
;
;
SWOUT:	PUSH	A		; Save 'A' and flags
	LDA	RTBNK		; Get the bank to return to
	CALL	BNKSEL		; Return to that bank
	POP	A		; Restore 'A' and flags
	RET
;.....
;
;
JTBLNEW:JMP	MCBOOT		; Cold boot
	JMP	WBCOMN		; Warm boot
	JMP	CSCOMN		; Modem status test
	JMP	CICOMN		; Modem input routine
	JMP	COCOMN		; Modem output routine
;
	 IF	NOT HARDLOG
	JMP	COCOMN		; Modem list device
	JMP	COCOMN		; Modem punch device
	JMP	CICOMN		; Modem reader device
	 ENDIF			; NOT HARDLOG
;
JTBLEN	EQU	$-JTBLNEW
;.....
;
;			       end
;-----------------------------------------------------------------------
